package com.ncu.filter;

import com.ncu.Enum.StatusCodeEnum;
import com.ncu.dto.UserDTO;
import com.ncu.exception.BizException;
import com.ncu.pojo.LoginUser;
import com.ncu.utils.JwtUtil;
import com.ncu.utils.RedisCache;
import com.ncu.utils.UserHolder;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

import static com.ncu.constant.RedisConst.LOGIN;

/**
 * jwt拦截器
 * 在security之前拦截
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    RedisCache redisCache;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        //1获取token  header的token
        String token = request.getHeader("token");
        if (!StringUtils.hasText(token)) {
            //放行，让后面的过滤器执行
            filterChain.doFilter(request, response);
            return;
        }
        //2解析token
        String userId;
        try {
            Claims claims = JwtUtil.parseJWT(token);
            userId = claims.getSubject();
        } catch (Exception e) {
//            throw new BizException("token不合法！", StatusCodeEnum.TOKEN_EXPIRED);
            //放行，让后面的过滤器执行
            filterChain.doFilter(request, response);
            return;
        }

        //3获取userId, redis获取用户信息
        LoginUser loginUser = redisCache.getCacheObject(LOGIN + userId);
        if (Objects.isNull(loginUser)) {
//            throw new BizException("账号过期，请重新登录！",StatusCodeEnum.TOKEN_EXPIRED);
            //放行，让后面的过滤器执行
            filterChain.doFilter(request, response);
            return;
        }
//


        //续命4小时
        redisCache.expire(LOGIN + userId,4*60*60);

        UserDTO userDTO = new UserDTO();
        userDTO.setId(loginUser.getUser().getId());
        userDTO.setNickName(loginUser.getUser().getUserName());
        userDTO.setAvatar(loginUser.getUser().getAvatar());
        userDTO.setUserName(loginUser.getUsername());
        //保存到线程中
        UserHolder.saveUser(userDTO);
        //也可以保存在这里
        request.setAttribute("currentUser",loginUser.getUser());


        //4封装Authentication
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken
                = new UsernamePasswordAuthenticationToken(loginUser, null,loginUser.getAuthorities());

//        //5存入SecurityContextHolder 后面的过滤器通过判断有没有Authentication来判断是否放行
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

        //放行，让后面的过滤器执行
        filterChain.doFilter(request, response);

        System.out.println("出来了");
        //把内容清空
        UserHolder.removeUser();
    }
}
